﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


using System.Drawing;
using System.IO;
using Util.ImageProcess;
using Newtonsoft.Json;
using BusinessClass.JsonClass;
using System.Drawing.Drawing2D;


namespace YLServerInterface.UserControls
{
    /// <summary>
    /// Interaction logic for ImageCutter.xaml
    /// </summary>
    public partial class ImageCutter : UserControl
    {

        ImageCutter()
        {
            InitializeComponent();
        }
        /// <summary>
        /// log没有传null
        /// </summary>
        /// <param name="ImgPath"></param>
        /// <param name="SaveImgPath"></param>
        /// <param name="RectWidth"></param>
        /// <param name="RectHeight"></param>
        /// <param name="log"></param>
        public ImageCutter(string ImgPath, string SaveImgPath, double RectWidth, double RectHeight, CutResult log)
            : this()
        {
            if (SaveImgPath.Length == 0)
            {
                CanCut = false;
            }
            else
            {
                CanCut = true;
            }
            this.ImgPath = ImgPath;
            this.SaveImgPath = SaveImgPath;
            this.RectWidth = RectWidth;
            this.RectHeight = RectHeight;
            this.log = log;
        }
        public SmoothingMode qulityMode = SmoothingMode.HighQuality;
        public SmoothingMode QulityMode { get { return qulityMode; } set { qulityMode = value; } }
        public CutResult log;
        public string ImgPath { get; set; }
        private string saveImgPath;
        public string SaveImgPath
        {
            get
            {
                return saveImgPath;
            }
            set
            {
                saveImgPath = value;
                if (value != null && value.Length > 0)
                {

                    tbSaveName.Text = Common.getFileName(saveImgPath);
                }
                else
                {
                    tbSaveName.Text = "不会裁剪";
                }
            }
        }
        /// <summary>
        ///截图宽度
        /// </summary>
        public double RectWidth { get; set; }
        /// <summary>
        /// 截图高度
        /// </summary>
        public double RectHeight { get; set; }
        private bool canCut;
        /// <summary>
        /// 无法裁剪图片，1图片尺寸不足，2图片不是必须的，3图片已存在（重复生成的时候不要裁剪）
        /// </summary>
        public bool CanCut
        {
            get { return canCut; }
            set
            {
                if (value == false && log == null)
                {
                    rect.Visibility = System.Windows.Visibility.Hidden;
                }
                canCut = value;
            }
        }
        /// <summary>
        /// 原始图片
        /// </summary>
        private BitmapImage bitmapImg;
        /// <summary>
        /// 初始时的宽度
        /// </summary>
        float rectOrignalWidth;
        /// <summary>
        /// 初始时的高度
        /// </summary>
        float rectOrignalHeight;
        /// <summary>
        /// 是否是第一次设置框框
        /// </summary>
        bool isRending = true;



        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            //载入实际图片
            bitmapImg = new BitmapImage(new Uri(ImgPath));
            #region 使用缩略图，以提升速度
            var thumbnails = new BitmapImage();
            thumbnails.BeginInit();
            thumbnails.DecodePixelWidth = 200;
            thumbnails.UriSource = new Uri(ImgPath);
            thumbnails.EndInit();
            img.Source = thumbnails;
            #endregion
            #region 图片大小检查
            if (bitmapImg.PixelWidth < RectWidth || bitmapImg.PixelHeight < RectHeight)
            {
                CanCut = false;
                labError.Visibility = System.Windows.Visibility.Visible;
                return;
            }
            #endregion

            canvas.DataContext = this;
        }
        /// <summary>
        /// 重新设置裁剪参数
        /// </summary>
        /// <param name="SaveImgPath"></param>
        /// <param name="RectWidth"></param>
        /// <param name="RectHeight"></param>
        //public void UpdateConfig(string SaveImgPath, double RectWidth, double RectHeight)
        //{
        //    this.SaveImgPath = SaveImgPath;
        //    this.RectWidth = RectWidth;
        //    this.RectHeight = RectHeight;
        //    isRending = true;
        //    updateRect();
        //}

        public void SwapConfig(ImageCutter imgCutter)
        {
            {
                var t = SaveImgPath;
                SaveImgPath = imgCutter.SaveImgPath;
                imgCutter.SaveImgPath = t;
            }
            {
                var t = RectWidth;
                RectWidth = imgCutter.RectWidth;
                imgCutter.RectWidth = t;
            }
            {
                var t = RectHeight;
                RectHeight = imgCutter.RectHeight;
                imgCutter.RectHeight = t;
            }
            {
                var t = CanCut;
                CanCut = imgCutter.CanCut;
                imgCutter.CanCut = t;
            }
            isRending = true;
            UpdateRect();
            imgCutter.isRending = true;
            imgCutter.UpdateRect();
        }
        #region 图片伸缩时
        private void img_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateRect();
        }
        /// <summary>
        /// 控件被改变大小是要改变框框，因为控件被改变的时候里面的图片大小也会被改变
        /// </summary>
        /// <param name="e"></param>
        public void UpdateRect()
        {
            #region  第一次时设置初始化框框大小
            if (isRending && CanCut)
            {

                rect.Visibility = System.Windows.Visibility.Visible;
                var imgWidth = bitmapImg.PixelWidth;
                var imgControlWidth = img.ActualWidth;
                double widthScale = imgControlWidth / imgWidth;

                var imgHeight = bitmapImg.PixelHeight;
                var imgControlHeight = img.ActualHeight;
                var heightScale = imgControlHeight / imgHeight;


                rectOrignalWidth = (float)widthScale * (float)RectWidth;
                rectOrignalHeight = (float)heightScale * (float)RectHeight;
                isRending = false;
                var exceptWidth = RectWidth * widthScale;
                var exceptHeight = RectHeight * heightScale;
                #region 把裁剪框变最大
                var imgCScale = imgControlHeight / imgControlWidth;
                var retCScale = exceptHeight / exceptWidth;
                if (imgCScale > retCScale)
                {//裁剪框 宽增加
                    var scale = RectWidth / RectHeight;
                    rect.Width = imgControlWidth;
                    rect.Height = rect.Width / scale;
                }
                else
                { //高增加
                    var scale = RectWidth / RectHeight;
                    rect.Height = imgControlHeight;
                    rect.Width = rect.Height * scale;
                }
                #endregion
                //if (exceptWidth / imgControlWidth < 0.7 && exceptHeight / imgControlHeight < 0.7)
                //{
                //    var scale = RectWidth / RectHeight;
                //    rect.Width = imgControlWidth * 0.5;
                //    rect.Height = rect.Width / scale;
                //}
                //else
                //{
                //    rect.Width = exceptWidth;
                //    rect.Height = exceptHeight;
                //}

                //移动到中心
                Canvas.SetLeft(rect, imgControlWidth / 2 - rect.Width / 2);
                Canvas.SetTop(rect, imgControlHeight / 2 - rect.Height / 2);
                #region 展示上一次操作的情况
                if (log != null) //展示上一次操作的情况
                {
                    CanCut = false; //已经截图过了不用再做
                    double offxScale = log.RectOffsetXScale_BaseOnContainer;
                    double offyScale = log.RectOffsetYScale_BaseOnContainer;
                    double scale = log.RectSizeRenderingScale_BaseOnConfig;
                    Canvas.SetLeft(rect, offxScale * this.vbContainer.ActualWidth);
                    Canvas.SetTop(rect, offyScale * this.vbContainer.ActualHeight);
                    this.rect.Width = scale * RectWidth;
                    this.rect.Height = scale * RectHeight;
                }
                #endregion
            }
            else
                rect.Visibility = System.Windows.Visibility.Hidden;
            #endregion
        }
        #endregion

        #region 截图
        /// <summary>
        /// 执行剪切图片，并且根据传入名字进行保存
        /// </summary>
        /// <param name="outputImgName"></param>
        public CutResult Cut()
        {
            #region 参数验证
            if (CanCut == false)
            {
                return null;
            }
            if (SaveImgPath == "")
            {
                return null;
            }
            #endregion
            //删掉已经生成的截图图片，重新生成
            if (File.Exists(SaveImgPath))
            {
                File.Delete(SaveImgPath);
            }
            using (Bitmap bitmap = new Bitmap(ImgPath))
            {
                //原先是1000  现在是100  那么x缩写10倍
                float xScalef = getXScaleF(bitmap.Width);
                float yScalef = getYScaleF(bitmap.Height);
                double left = Canvas.GetLeft(rect);
                double top = Canvas.GetTop(rect);
                //框框控件的信息
                PointF rectLeftTopPosition = new PointF((float)left, (float)top);
                //根据框框信息，计算出实际在图片中截取的左上角坐标
                PointF rectLeftTopAtImgPosition = getOrignalPosition(rectLeftTopPosition, xScalef, yScalef);
                //剪裁图片大小
                #region 框框变大后，原来截取的范围也要变大
                var rectXChangeScale = rect.Width / rectOrignalWidth;
                var rectYChangeScale = rect.Height / rectOrignalHeight;
                var imgSizef = new SizeF(
                    (float)(rectXChangeScale * RectWidth),
                    (float)(rectYChangeScale * RectHeight));
                #endregion
                RectangleF rectf = new RectangleF(rectLeftTopAtImgPosition, imgSizef);
                //复制图片指定位置
                using (var cutterBitmap = bitmap.Clone(rectf, bitmap.PixelFormat))
                {
                    //缩小分辨率，输出。
                    using (Bitmap emptyImg = new Bitmap((int)RectWidth, (int)RectHeight))
                    {
                        using (Graphics graphics = Graphics.FromImage(emptyImg))
                        {
                            graphics.SmoothingMode = QulityMode; ;
                            //graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
                            graphics.DrawImage(cutterBitmap, new RectangleF(0, 0, emptyImg.Width, emptyImg.Height));
                            emptyImg.Save(SaveImgPath);
                        }
                    }
                }
            }

            //添加操作的信息 以供记录
            var rect_left = Canvas.GetLeft(rect);
            var rect_top = Canvas.GetTop(rect);

            CutResult ret = new CutResult()
            {
                FileName = tbSaveName.Text,
                RectOffsetXScale_BaseOnContainer = rect_left / vbContainer.ActualWidth,
                RectOffsetYScale_BaseOnContainer = rect_top / vbContainer.ActualHeight,
                RectSizeRenderingScale_BaseOnConfig = rect.ActualHeight / RectHeight
            };
            return ret;
        }

        private float getXScaleF(int imgWidth)
        {
            return (float)((1.0f * imgWidth) / (1.0f * this.img.ActualWidth));//后者是控件呈现时候的宽度
        }
        private float getYScaleF(int imgHeight)
        {
            return (float)((1.0f * imgHeight) / (1.0f * this.img.ActualHeight));
        }
        private PointF getOrignalPosition(PointF p, float xScale, float yScale)
        {
            return new PointF(p.X * xScale, p.Y * yScale);
        }

        #endregion

        #region 滚轮截取框大小
        /// <summary>
        /// 鼠标滚轴增加减少因子
        /// </summary>  
        private float rectXYScaleFactor = 1.05f;

        private void rect_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            CanCut = true;//改变大小是 如果已经生成过 就也可以剪裁
            Func<ContentControl, double, bool> checkSize = (rect, factor) =>
            {
                return !(rect.Width * factor + Canvas.GetLeft(rect) > img.ActualWidth ||
                    rect.Height * factor + Canvas.GetTop(rect) > img.ActualHeight);
            };
            if (e.Delta > 0)
            {
                if (checkSize(rect, rectXYScaleFactor))
                {
                    rect.Width *= rectXYScaleFactor;
                    rect.Height *= rectXYScaleFactor;
                }
            }
            else
            {
                if (checkSize(rect, 1 / rectXYScaleFactor))
                {
                    rect.Width /= rectXYScaleFactor;
                    rect.Height /= rectXYScaleFactor;
                }
            }
        }

        #endregion


        public Action<ImageCutter> MoveLeft;
        public Action<ImageCutter> MoveRight;


        private void mLeft_Click(object sender, RoutedEventArgs e)
        {
            MoveLeft(this);
        }

        private void mRight_Click(object sender, RoutedEventArgs e)
        {
            MoveRight(this);
        }

        private void rect_MouseEnter(object sender, MouseEventArgs e)
        {
            rect.Focus();

        }



    }
}
